/**
 *
 */
package csh.cryptonite.api;

import java.io.File;
import java.io.IOException;

import android.util.Log;

import csh.cryptonite.ShellUtils;

/**
 * @author Nicholas Wilkie
 *
 */
public class EncFSManager {

	/*accept any key and decrypt different files based on the result if true. No reason to make this true yet*/
	private boolean cbAnykey = false;
	
	String encFSBinPath = "/data/data/csh.cryptonite/encfs"; //Todo: set this!
	String encFSBinDirPath = "/data/data/csh.cryptonite"; //Todo: set this!
	
	public String testMountEncFSVolume() {
		return mountEncFSVolume("/storage/sdcard0/Encrypted", "/storage/sdcard0/csh.cryptonite/mnt", "ENTER PASSWORD HERE");
	}
	
	//[/data/data/csh.cryptonite/encfs, , , --public, , --stdinpass, "/storage/sdcard0/Encrypted", "/storage/sdcard0/csh.cryptonite/mnt"]
	//bindirpath = /data/data/csh.cryptonite
	//toStdIn = ***thepassword***
	//root = true
	public String mountEncFSVolume(String encryptedDirectory, String mntDirectory, String password) {
		if (!isValidMountDirectory(mntDirectory)) {
			//Return error
			throw new IllegalArgumentException("Invalid mount directory location");
		}
		
		//Possibly run this in a new thread
		
		//if we end up using one...
		String configOverride = "";
        //configOverride = "--config=" + configPath;
		
		//Deal with 4.2 bug
        String foreground = ShellUtils.isAndroid42() ? "-f" : "";
        //Assemble commands
        String[] cmdlist = { encFSBinPath, configOverride, foreground,
            "--public", cbAnykey ? "--anykey" : "", "--stdinpass", "\"" + encryptedDirectory + "\"",
            "\"" + mntDirectory + "\"" };
        
        //Log the contents of the command list
        Log.d("EncFSManager", "Command list to encfs..." + cmdlist.toString());
        
        //Output of shell call to encfs. Empty string if any problems
        String encfsoutput = null;
        
        try {
            if (!ShellUtils.isAndroid42()) {
                encfsoutput = ShellUtils.runBinary(cmdlist,
                                                   encFSBinDirPath,
                                                   password, true);
            } else {
                encfsoutput = ShellUtils.hijackDebuggerd42(cmdlist,
                                                           password);
            }
        } catch (IOException e) {
            //deal with exception
        } catch (InterruptedException e) {
            //deal with exception
        }
        
        return encfsoutput;
	}
	
	
	
    /**
	 * 
	 */
	private boolean isValidMountDirectory(String directory) {
		boolean isValid = true;
		try {
			File f = new File(directory);
			isValid = isValid && f.isDirectory();
			isValid = isValid && f.canRead() && f.canWrite();
			isValid = isValid && f.list().length == 0;
		} catch (Exception e) {
			return false;
		}
		return isValid;
	}
	
	String configFile = "/storage/sdcard0/Encrypted/.encfs6.xml"; //the xml file with the encryption info. Storage.ENCFS_XML_CURRENT signifies the name
	//DirectorySettings.INSTANCE.encFSBin is configured in CryptoniteActivity.onCreate()
	
	
    /** This will run the shipped encfs binary and spawn a daemon on rooted devices
     */
    /*    private void mountEncFS(final String srcDir) { //dir with encrypted files
     if (currentConfigPath == null) {//currentConfigPath can be empty
     if (currentConfigPath.length() > 0) {
     if (Cryptonite.jniIsValidEncFS(srcDir) != Cryptonite.jniSuccess()) {
     showToast(R.string.invalid_encfs);
     Log.v(CryptoniteActivity.TAG, "Invalid EncFS");
     return;
     }
     }
     }
     if (!CryptoniteActivity.isValidMntDir(this, new File(DirectorySettings.INSTANCE.mntDir), true)) { //basic checks for writability, that it's a directory, etc.
     showToast(R.string.mount_point_invalid);			//DirectorySettings.INSTANCE.mntDir is where the decrypted drive gets mounted
     return;
     }
     ProgressDialogFragment.showDialog(this, R.string.running_encfs, "mountEncFS");
     Log.v(CryptoniteActivity.TAG, "Running encfs with " + srcDir + " " + DirectorySettings.INSTANCE.mntDir); //return DirectorySettings.getGlobalExternalStorageDirectory().getPath() + MNTPNT;
     alertMsg = "";
     new Thread(new Runnable() {
     public void run() {
     SharedPreferences prefs = getBaseContext().getSharedPreferences(CryptoniteActivity.ACCOUNT_PREFS_NAME, 0);
     String encfsoutput = "";
     MountManager.INSTANCE.setEncFSPath(currentPath); //encrypted directory
     String configOverride = "";
     MountManager.INSTANCE.setEncFSConfigPath("");
     if (currentConfigPath != null) { //it can be empty and not null apparently. If you want to override "fill configOverride" then this can have something.
     if (currentConfigPath.length() > 0) {
     MountManager.INSTANCE.setEncFSConfigPath(currentConfigPath);
     configOverride = "--config=" + MountManager.INSTANCE.getEncFSConfigPath();
     }
     }
     currentConfigPath = null;
     String foreground = ShellUtils.isAndroid42() ? "-f" : ""; //apparently 4.2 needs the -f?
     String[] cmdlist = { DirectorySettings.INSTANCE.encFSBin, configOverride, foreground, //MAGIC GETS CONFIGURED HERE
     "--public", prefs.getBoolean("cb_anykey", false) ? "--anykey" : "", "--stdinpass", "\"" + srcDir + "\"", //[/data/data/csh.cryptonite/encfs, , , --public, , --stdinpass, "/storage/sdcard0/Encrypted", "/storage/sdcard0/csh.cryptonite/mnt"]
     "\"" + DirectorySettings.INSTANCE.mntDir + "\"" };
     try {
     if (!ShellUtils.isAndroid42()) {
     encfsoutput = ShellUtils.runBinary(cmdlist,
     DirectorySettings.INSTANCE.binDirPath,
     currentPassword, true);									// Run the binary
     } else {
     encfsoutput = ShellUtils.hijackDebuggerd42(cmdlist,
     currentPassword);										// Run the binary for 4.2
     }
     } catch (IOException e) {
     alertMsg = getString(R.string.mount_fail) + ": "
     + e.getMessage();
     } catch (InterruptedException e) {
     alertMsg = getString(R.string.mount_fail) + ": "
     + e.getMessage();
     }
     final String fEncFSOutput = encfsoutput;								// Empty if it worked
     Mounted?
     if (!ShellUtils.isMounted("fuse.encfs")) {
     alertMsg = getString(R.string.mount_fail);
     }
     runOnUiThread(new Runnable() {
     public void run() {
     ProgressDialogFragment.dismissDialog(FileDialog.this, "mountEncFS");
     nullPassword();
     if (!alertMsg.equals("")) {
     showToast(alertMsg + ": " + fEncFSOutput);
     getIntent().putExtra(RESULT_OPEN_PATH, (String)null);
     getIntent().putExtra(RESULT_UPLOAD_PATH, (String)null);
     getIntent().putExtra(RESULT_EXPORT_PATHS, currentPath);
     getIntent().putExtra(RESULT_SELECTED_FILE, (String)null);
     setResult(CryptoniteActivity.RESULT_RETRY, getIntent());
     finish();
     } else {
     showToast(getString(R.string.encfs_success_mount)
     + " " + DirectorySettings.INSTANCE.mntDir);
     getIntent().putExtra(RESULT_OPEN_PATH,
     (String) null);
     getIntent().putExtra(RESULT_UPLOAD_PATH,
     (String) null);
     getIntent().putExtra(RESULT_EXPORT_PATHS,
     currentPath);
     getIntent().putExtra(RESULT_SELECTED_FILE,
     (String) null);
     setResult(RESULT_OK, getIntent());
     finish();
     }
     }
     });
     }
     }).start();
     }
     
     *//** Initialize an EncFS volume. This will check
        * whether the EncFS volume is valid and initialize the EncFS
        * root information
        *
        * @param srcDir Path to EncFS volume
        * @param pwd password
        *//*
           private void initEncFS(final String srcDir) {
           alertMsg = "";
           alertCode = CryptoniteActivity.RESULT_OK;
           
           ProgressDialogFragment.showDialog(this, R.string.running_encfs, "initEncFS");
           new Thread(new Runnable() {
           public void run() {
           if (StorageManager.INSTANCE.getEncFSStorage() == null) {
           alertMsg = getString(R.string.internal_error);
           alertCode = CryptoniteActivity.RESULT_RETRY;
           } else {
           String referencePath = intentStartPath;
           if (selectionMode == SelectionMode.MODE_OPEN_DEFAULT_DB) {
           referencePath = currentRoot;
           }
           if (!StorageManager.INSTANCE.getEncFSStorage()
           .initEncFS(srcDir, currentRoot, currentConfigPath)) {
           alertMsg = getString(R.string.invalid_encfs);
           alertCode = CryptoniteActivity.RESULT_RETRY;
           // StorageManager.INSTANCE.resetEncFSStorage();
           } else {
           DirectorySettings.INSTANCE.currentBrowsePath = currentPath;
           DirectorySettings.INSTANCE.currentBrowseStartPath = referencePath;
           switch (selectionMode) {
           case SelectionMode.MODE_OPEN_DEFAULT_DB:
           case SelectionMode.MODE_OPEN_ENCFS_DB: {
           try {
           StorageManager.INSTANCE.setEncFSPath(currentPath
           .substring(referencePath.length()));
           } catch (StringIndexOutOfBoundsException e) {
           alertMsg = getString(R.string.decrypt_failure) +
           " currentPath: " + currentPath +
           " intentStartPath: " + intentStartPath;
           alertCode = CryptoniteActivity.RESULT_RETRY;
           Log.v(CryptoniteActivity.TAG, alertMsg);
           }
           break;
           }
           default:
           StorageManager.INSTANCE.setEncFSPath(currentPath);
           }
           Log.i(CryptoniteActivity.TAG, "Dialog root is " + currentPath);
           
           SharedPreferences prefs = getBaseContext().getSharedPreferences(CryptoniteActivity.ACCOUNT_PREFS_NAME, 0);
           StorageManager.INSTANCE.setEncFSConfigPath("");
           if (currentConfigPath != null) {
           if (currentConfigPath.length() > 0) {
           StorageManager.INSTANCE.setEncFSConfigPath(currentConfigPath);
           }
           }
           currentConfigPath = null;
           if (Cryptonite.jniInit(srcDir, currentPassword,
           prefs.getBoolean("cb_anykey", false),
           StorageManager.INSTANCE.getEncFSConfigPath()) != Cryptonite.jniSuccess())
           {
           Log.v(CryptoniteActivity.TAG, getString(R.string.browse_failed));
           alertMsg = getString(R.string.browse_failed);
           alertCode = CryptoniteActivity.RESULT_RETRY;
           // StorageManager.INSTANCE.resetEncFSStorage();
           } else {
           Log.v(CryptoniteActivity.TAG, "Decoding succeeded");
           }
           }
           }
           runOnUiThread(new Runnable() {
           public void run() {
           ProgressDialogFragment.dismissDialog(FileDialog.this, "initEncFS");
           nullPassword();
           if (alertCode != CryptoniteActivity.RESULT_OK) {
           showToast(alertMsg);
           getIntent().putExtra(RESULT_OPEN_PATH, (String)null);
           getIntent().putExtra(RESULT_UPLOAD_PATH, (String)null);
           getIntent().putExtra(RESULT_EXPORT_PATHS, currentPath);
           getIntent().putExtra(RESULT_SELECTED_FILE, (String)null);
           setResult(alertCode, getIntent());
           finish();
           } else {
           showToast(R.string.encfs_success);
           getIntent().putExtra(RESULT_OPEN_PATH, (String)null);
           getIntent().putExtra(RESULT_UPLOAD_PATH, (String)null);
           getIntent().putExtra(RESULT_EXPORT_PATHS, currentPath);
           getIntent().putExtra(RESULT_SELECTED_FILE, (String)null);
           setResult(RESULT_OK, getIntent());
           finish();
           }
           }
           });
           }
           }).start();
           }*/
    
    
}
